/*
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package top.continew.admin.asset.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;
import top.continew.admin.asset.mapper.DeviceDiscardMapper;
import top.continew.admin.asset.mapper.DeviceLendMapper;
import top.continew.admin.asset.mapper.DeviceTracksMapper;
import top.continew.admin.asset.model.entity.*;
import top.continew.admin.asset.model.req.DeviceTracksReq;
import top.continew.starter.core.validation.CheckUtils;
import top.continew.starter.extension.crud.model.query.PageQuery;
import top.continew.starter.extension.crud.model.resp.PageResp;
import top.continew.starter.extension.crud.service.BaseServiceImpl;
import top.continew.admin.asset.mapper.DeviceRecordsMapper;
import top.continew.admin.asset.model.query.DeviceRecordsQuery;
import top.continew.admin.asset.model.req.DeviceRecordsReq;
import top.continew.admin.asset.model.resp.DeviceRecordsDetailResp;
import top.continew.admin.asset.model.resp.DeviceRecordsResp;
import top.continew.admin.asset.service.DeviceRecordsService;

import java.util.List;

/**
 * 设备清单业务实现
 *
 * @author CharlieYan
 * @since 2025/03/18 10:12
 */
@Service
@RequiredArgsConstructor
public class DeviceRecordsServiceImpl extends BaseServiceImpl<DeviceRecordsMapper, DeviceRecordsDO, DeviceRecordsResp, DeviceRecordsDetailResp, DeviceRecordsQuery, DeviceRecordsReq> implements DeviceRecordsService {

    private final DeviceRecordsMapper deviceRecordsMapper;

    private final DeviceTracksMapper deviceTracksMapper;

    private final DeviceLendMapper deviceLendMapper;

    private final DeviceDiscardMapper deviceDiscardMapper;

    @Override
    public Integer deleteReturn(Long id) {
        DeviceRecordsDO deviceRecordsDO = new DeviceRecordsDO();
        deviceRecordsDO.setId(id);
        deviceRecordsDO.setIsDel(1);
        return deviceRecordsMapper.updateById(deviceRecordsDO);
    }

    /**
     * 新增设备
     * 
     * @param req
     * @return
     */
    @Override
    public Long create(DeviceRecordsReq req) {
        // 1. 新增设备主表
        Long deviceId = super.create(req);

        // 2. 增加履历表
        DeviceTracksDO deviceTracksDO = new DeviceTracksDO();
        deviceTracksDO.setDeviceId(deviceId);
        deviceTracksDO.setCarryName("新增");

        String content = "新增设备，备注： " + req.getDescription();
        deviceTracksDO.setContent(content);
        return Long.valueOf(deviceTracksMapper.insert(deviceTracksDO));
    }

    @Override
    public PageResp<DeviceRecordsResp> page(DeviceRecordsQuery query, PageQuery pageQuery) {
        QueryWrapper<DeviceRecordsDO> queryWrapper = this.buildQueryWrapper(query);
        super.sort(queryWrapper, pageQuery);
        IPage<DeviceRecordsDetailResp> page = baseMapper.selectDeviceRecordsPage(new Page<>(pageQuery
            .getPage(), pageQuery.getSize()), queryWrapper);
        PageResp<DeviceRecordsResp> pageResp = PageResp.build(page, super.getListClass());
        pageResp.getList().forEach(this::fill);
        return pageResp;
    }

    @Override
    protected QueryWrapper<DeviceRecordsDO> buildQueryWrapper(DeviceRecordsQuery query) {
        String fuzzy = query.getFuzzy();
        Integer status = query.getStatus();
        Integer isDel = query.getIsDel();
        return new QueryWrapper<DeviceRecordsDO>().and(StrUtil.isNotBlank(fuzzy), q -> q.like("tt.name", fuzzy)
            .or()
            .like("tt.name", fuzzy)
            .or()
            .like("tt.category_name", fuzzy)
            .or()
            .like("tt.brand", fuzzy)
            .or()
            .like("tt.model", fuzzy)
            .or()
            .like("tt.code", fuzzy)
            .or()
            .like("tt.sn", fuzzy)

        ).eq(null != status, "tt.status", status).eq(null != isDel, "tt.is_del", isDel);
    }

    @Override
    protected void beforeCreate(DeviceRecordsReq req) {
        final String errorMsgTemplate = "新增失败，[{}] 编号已存在";
        String code = req.getCode();
        CheckUtils.throwIf(this.isNameExists(code), errorMsgTemplate, code);
    }

    @Override
    public List<String> getDeviceBrandByCategoryId(Long categoryId) {
        return baseMapper.selectDeviceBrandByCategoryId(categoryId);
    }

    @Override
    public List<String> getDeviceModelByCategoryId(Long categoryId) {
        return baseMapper.selectDeviceModelByCategoryId(categoryId);
    }

    /**
     * 设备编码是否存在
     *
     * @param code 设备编码
     * @return 是否存在
     */
    private boolean isNameExists(String code) {
        Long count = baseMapper.selectCountByCode(code);
        return null != count && count > 0;
    }

    @Override
    public void delete(List<Long> ids) {
        this.batchSoftDelete(ids);
    }

    /**
     * 批量更新
     * 
     * @param ids
     */
    @Transactional
    public void batchSoftDelete(List<Long> ids) {
        // 直接更新（推荐）
        LambdaUpdateWrapper<DeviceRecordsDO> wrapper = Wrappers.lambdaUpdate();
        wrapper.in(DeviceRecordsDO::getId, ids).set(DeviceRecordsDO::getIsDel, 2);
        deviceRecordsMapper.update(null, wrapper);
    }

    /**
     * 设备分配用户
     * 
     * @param useDO
     * @return
     */
    @Override
    public Integer deviceUse(DeviceUseDO useDO) {
        // 1. 修改设备主表信息
        DeviceRecordsDO deviceRecordsDO = new DeviceRecordsDO();
        deviceRecordsDO.setId(useDO.getDeviceId());
        deviceRecordsDO.setDeptId(useDO.getDeptId());
        deviceRecordsDO.setUserId(useDO.getUserId());
        deviceRecordsDO.setStatus(2);
        deviceRecordsMapper.updateById(deviceRecordsDO);

        // 2. 新增设备履历记录
        DeviceTracksDO deviceTracksDO = new DeviceTracksDO();
        deviceTracksDO.setDeviceId(useDO.getDeviceId());
        deviceTracksDO.setCarryName("分配");

        // 设备使用人名称
        String userName = deviceTracksMapper.selectNicknameById(useDO.getUserId());
        String content = "将设备分配给 ‘" + userName + "’，备注： " + useDO.getContent();
        deviceTracksDO.setContent(content);
        return deviceTracksMapper.insert(deviceTracksDO);

    }

    /**
     * 设备借用
     * 
     * @param lendDO
     * @return
     */
    @Override
    public Integer deviceLend(DeviceLendDO lendDO) {
        DeviceRecordsDO deviceRecordsDO = new DeviceRecordsDO();
        deviceRecordsDO.setId(lendDO.getDeviceId());
        deviceRecordsDO.setStatus(3);
        deviceRecordsMapper.updateById(deviceRecordsDO);

        // 1. 添加借用数据
        deviceLendMapper.insert(lendDO);

        // 2. 新增设备履历记录
        DeviceTracksDO deviceTracksDO = new DeviceTracksDO();
        deviceTracksDO.setDeviceId(lendDO.getDeviceId());
        deviceTracksDO.setCarryName("借用");
        // 设备借用人名称
        String userName = deviceTracksMapper.selectNicknameById(lendDO.getUserId());
        String content = "‘" + userName + "’ " + lendDO.getLendDate() + "借用该设备，预计归还日期：" + lendDO
            .getPlanDate() + "。备注：" + lendDO.getLendDescription();
        deviceTracksDO.setContent(content);
        return deviceTracksMapper.insert(deviceTracksDO);

    }

    /**
     * 设备归还
     * 
     * @param lendDO
     * @return
     */
    @Override
    public Integer deviceReturn(DeviceLendDO lendDO) {

        DeviceRecordsDO deviceRecordsDO = new DeviceRecordsDO();
        deviceRecordsDO.setId(lendDO.getDeviceId());
        deviceRecordsDO.setStatus(1);
        deviceRecordsMapper.updateById(deviceRecordsDO);

        Long deviceId = lendDO.getDeviceId();
        DeviceLendDO deviceLendDO = deviceLendMapper.selectDeviceLendLimit1ByDeviceId(deviceId);
        deviceLendDO.setDeviceId(deviceId);
        deviceLendDO.setReturnDate(lendDO.getReturnDate());
        deviceLendDO.setReturnDescription(lendDO.getReturnDescription());
        // 1. 更新借用数据
        deviceLendMapper.updateById(deviceLendDO);

        // 2. 新增设备履历记录
        DeviceTracksDO deviceTracksDO = new DeviceTracksDO();
        deviceTracksDO.setDeviceId(lendDO.getDeviceId());
        deviceTracksDO.setCarryName("归还");
        // 设备使用人名称
        String userName = deviceTracksMapper.selectNicknameById(deviceLendDO.getUserId());
        String content = "‘" + userName + "’ " + lendDO.getReturnDate() + "归还该设备。备注：" + lendDO.getReturnDescription();
        deviceTracksDO.setContent(content);
        return deviceTracksMapper.insert(deviceTracksDO);
    }

    /**
     * 设备报废
     * 
     * @param discardDO
     * @return
     */
    @Override
    public Integer deviceDiscard(DeviceDiscardDO discardDO) {
        // 修改设备状态
        DeviceRecordsDO deviceRecordsDO = new DeviceRecordsDO();
        deviceRecordsDO.setId(discardDO.getDeviceId());
        deviceRecordsDO.setStatus(5);
        deviceRecordsMapper.updateById(deviceRecordsDO);

        // 1. 新增报废数据
        deviceDiscardMapper.insert(discardDO);

        // 2. 新增设备履历记录
        DeviceTracksDO deviceTracksDO = new DeviceTracksDO();
        deviceTracksDO.setDeviceId(discardDO.getDeviceId());
        deviceTracksDO.setCarryName("报废");
        // 设备使用人名称
        String userName = deviceTracksMapper.selectNicknameById(discardDO.getUserId());
        String content = "设备已报废。备注：" + discardDO.getDiscardDescription();
        deviceTracksDO.setContent(content);
        return deviceTracksMapper.insert(deviceTracksDO);

    }

    /**
     * 撤销报废
     * 
     * @param discardDO
     * @return
     */
    @Override
    public Integer deviceDiscardCancel(DeviceDiscardDO discardDO) {
        // 修改设备状态
        DeviceRecordsDO deviceRecordsDO = new DeviceRecordsDO();
        deviceRecordsDO.setId(discardDO.getDeviceId());
        deviceRecordsDO.setStatus(1);
        deviceRecordsMapper.updateById(deviceRecordsDO);

        Long deviceId = discardDO.getDeviceId();
        DeviceDiscardDO deviceDiscardDO = deviceDiscardMapper.selectDeviceDiscardLimit1ByDeviceId(deviceId);
        deviceDiscardDO.setDeviceId(deviceId);
        deviceDiscardDO.setCancelDescription(discardDO.getCancelDescription());
        // 1. 更新借用数据
        deviceDiscardMapper.updateById(deviceDiscardDO);

        // 2. 新增设备履历记录
        DeviceTracksDO deviceTracksDO = new DeviceTracksDO();
        deviceTracksDO.setDeviceId(discardDO.getDeviceId());
        deviceTracksDO.setCarryName("撤销报废");
        // 设备使用人名称
        String userName = deviceTracksMapper.selectNicknameById(deviceDiscardDO.getUpdateUser());
        String content = "‘" + userName + "’ 做了该设备的撤销报废操作。备注：" + deviceDiscardDO.getCancelDescription();
        deviceTracksDO.setContent(content);
        return deviceTracksMapper.insert(deviceTracksDO);

    }

    /**
     * 设备报修
     * 
     * @param req
     */
    @Override
    public void deviceMaintenance(DeviceTracksReq req) {

    }

}